// 加载环境变量配置
import 'dotenv/config';
// 导入开发环境配置
import development from '#src/config/settings/default.js';
// 导入生产环境配置
import production from '#src/config/settings/production.js';
// 导入加密模块
import crypto from 'crypto';

/**
 * 配置管理类，用于管理不同环境下的配置信息
 */
class Config {
    /**
     * 构造函数，初始化环境信息和配置映射
     */
    constructor() {
        // 获取当前环境，默认为开发环境
        this.env = process.env.NODE_ENV || 'development';
        // 配置映射，存储不同环境的配置
        this.configMap = { development, production };
        // 加载当前环境的配置
        this.config = this._loadConfig();
    }

    /**
     * 加载当前环境的配置
     * @returns {Object} 合并后的配置对象
     */
    _loadConfig() {
        // 获取基础配置，若当前环境配置不存在则使用开发环境配置
        const baseConfig = this.configMap[this.env] || this.configMap.development;
        return {
            ...baseConfig,
            // Redis 配置
            redis: {
                // Redis 主机地址，默认为 localhost
                host: process.env.REDIS_HOST || 'localhost',
                // Redis 端口号，默认为 6379
                port: process.env.REDIS_PORT || 6379,
                // Redis 密码，默认为空
                password: process.env.REDIS_PASSWORD || '',
                // Redis 用户名，默认为空
                username: process.env.REDIS_USERNAME || '',
                // Redis 连接 URL，若未设置则自动生成
                url: process.env.REDIS_URL || `redis://${process.env.REDIS_HOST || 'localhost'}:${process.env.REDIS_PORT || 6379}`
            },
            // 是否为生产环境
            isProduction: this.env === 'production',
            // 当前环境名称
            currentEnv: this.env
        };
    }

    /**
     * 获取 JWT 密钥
     * @param {string} [configSecret] 配置中的 JWT 密钥
     * @returns {string} JWT 密钥
     */
    _getSecret(configSecret) {
        // 生产环境下必须从环境变量中获取 JWT 密钥
        if (this.config.isProduction) {
            const envSecret = process.env.JWT_SECRET;
            if (!envSecret) {
                throw new Error('JWT_SECRET environment variable is required in production');
            }
            return envSecret;
        }
        // 非生产环境下使用传入的密钥或生成随机密钥
        return configSecret || crypto.randomBytes(32).toString('hex');
    }

    /**
     * 生成刷新令牌的密钥
     * @returns {string} 刷新令牌的密钥
     */
    _generateRefreshSecret() {
        return crypto.randomBytes(64).toString('hex');
    }

    /**
     * 获取当前环境的配置
     * @returns {Object} 冻结后的当前环境配置对象
     */
    get envConfig() {
        return Object.freeze(this.config);
    }

    /**
     * 获取 Redis 配置
     * @returns {Object} 冻结后的 Redis 配置对象
     */
    get redisConfig() {
        return Object.freeze({
            // Redis 主机地址，默认为 localhost
            host: process.env.REDIS_HOST || 'localhost',
            // Redis 端口号，默认为 6379
            port: process.env.REDIS_PORT || 6379,
            // Redis 密码
            password: process.env.REDIS_PASSWORD,
            // Redis 用户名
            username: process.env.REDIS_USERNAME,
            // Redis 连接 URL，若未设置则自动生成
            url: process.env.REDIS_URL || `redis://${process.env.REDIS_HOST || 'localhost'}:${process.env.REDIS_PORT || 6379}`
        });
    }

    /**
     * 获取 JWT 配置
     * @returns {Object} 冻结后的 JWT 配置对象
     */
    get jwtConfig() {
       return Object.freeze({
            // JWT 密钥
            secret: this._getSecret(), // 移除默认值参数
            // 刷新令牌的密钥
            refreshSecret: process.env.JWT_REFRESH_SECRET || this._generateRefreshSecret(),
            // JWT 过期时间，默认为 2 小时
            expiresIn: this.config.jwt.expiresIn || '2h',
            // 刷新令牌过期时间，默认为 7 天
            refreshExpiresIn: this.config.jwt.refreshExpiresIn || '7d',
            // 加密算法
            algorithm: 'HS256',
            // 签发者
            issuer: this.config.jwt.issuer,
            // 受众，默认为 mall-api-clients
            audience: this.config.jwt.audience || 'mall-api-clients'
        });
    }

    /**
     * 获取数据库配置
     * @returns {Object} 冻结后的数据库配置对象
     */
    get dbConfig() {
        return Object.freeze({
            // 数据库主机地址
            host: this.config.db.host,
            // 数据库端口号，默认为 3306
            port: this.config.db.port || 3306,
            // 数据库用户名
            user: this.config.db.user,
            // 数据库密码
            password: this.config.db.password,
            // 数据库名称
            database: this.config.db.name,
            // 等待连接
            waitForConnections: true,
            // 最大连接数，默认为 10
            connectionLimit: this.config.db.pool?.max || 10,
            // 队列限制
            queueLimit: 0,
            // 生产环境下启用 SSL 连接
            ssl: this.config.isProduction ? { rejectUnauthorized: true } : null,
            // 时区
            timezone: '+08:00',
            // 连接超时时间
            connectTimeout: 10000,
            // 获取连接超时时间
            acquireTimeout: 10000
        });
    }
}

// 创建配置管理实例
const configManager = new Config();
// 导出配置管理实例
export default configManager;